package com.chatplus.application.client.pay;

import cn.hutool.core.text.CharSequenceUtil;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.wap.Client;
import com.alipay.easysdk.payment.wap.models.AlipayTradeWapPayResponse;
import com.aliyun.tea.TeaConverter;
import com.aliyun.tea.TeaModel;
import com.aliyun.tea.TeaPair;
import com.chatplus.application.client.pay.domain.request.alipay.AlipayOrderPayRequest;
import com.chatplus.application.client.pay.domain.response.alipay.AlipayOrderPayResponse;
import com.chatplus.application.common.exception.BadRequestException;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.common.util.MoneyUtils;
import com.chatplus.application.config.properties.AliPayProperties;
import com.chatplus.application.domain.entity.pay.PayRequestEntity;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * description:
 *
 * @author Min
 * @date 22:58 - 2021/2/23.
 */
@Component
public class AliPayClient {
    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(AliPayClient.class);
    public static final String BODY = "body";
    public static final String TIMEOUT_EXPRESS = "timeout_express";
    /**
     * 外部指定买家 扩展字段，校验外部指定买家用
     */
    public static final String EXT_USER_INFO = "ext_user_info";
    /**
     * 支付宝订单超时关闭时间  (3分钟)
     */
    public static final String ALIPAY_TIMEOUT_EXPRESS_VALUE = "30m";
    /**
     * 支付宝请求成功
     */
    public static final String REQUEST_SUCCESS = "10000";
    private final AliPayProperties aliPayProperties;

    public AliPayClient(AliPayProperties aliPayProperties) {
        this.aliPayProperties = aliPayProperties;
    }

    public void initOptions() {
        if (!aliPayProperties.isEnable()) {
            throw new BadRequestException("支付宝支付未开启");
        }
        Config config = new Config();
        config.appId = aliPayProperties.getAppId();
        config.protocol = aliPayProperties.getProtocol();
        config.gatewayHost = aliPayProperties.getGatewayHost();
        config.signType = aliPayProperties.getSignType();
        config.alipayPublicKey = aliPayProperties.getAlipayPublicKey();
        config.merchantPrivateKey = aliPayProperties.getMerchantPrivateKey();
        // 转账等操作需要公钥证书
        config.merchantCertPath = aliPayProperties.getMerchantCertPath();
        config.alipayCertPath = aliPayProperties.getAlipayCertPath();
        config.alipayRootCertPath = aliPayProperties.getAlipayRootCertPath();
        // 3参数可选
        config.notifyUrl = aliPayProperties.getNotifyUrl();
        config.encryptKey = aliPayProperties.getEncryptKey();
        config.signProvider = aliPayProperties.getSignProvider();
        Factory.setOptions(config);
    }
    public AlipayOrderPayResponse wapPay(AlipayOrderPayRequest request) throws Exception {
        initOptions();
        String subject = request.getSubject();
        String payTransactionId = request.getPayTransactionId();
        String money = MoneyUtils.convertCentToYuan(request.getMoney());
        Client wap = Factory.Payment.Wap();
        wap.optional(TIMEOUT_EXPRESS, ALIPAY_TIMEOUT_EXPRESS_VALUE);
        if (CharSequenceUtil.isNotEmpty(request.getRemark())) {
            wap.optional(BODY, request.getRemark());
        }
        AlipayTradeWapPayResponse response = wapGetPay(wap, subject, payTransactionId, money, null, null);
        AlipayOrderPayResponse result = new AlipayOrderPayResponse();
        result.setResponseCode(REQUEST_SUCCESS);
        result.setResponseMsg("");
        result.setActionUrl(response.body);
        result.setAppId(wap._kernel.getConfig("appId"));
        return result;
    }

    private AlipayTradeWapPayResponse wapGetPay(Client wap, String subject, String outTradeNo, String totalAmount, String quitUrl, String returnUrl) throws Exception {
        Map<String, String> systemParams = TeaConverter.buildMap(
                new TeaPair("method", "alipay.trade.wap.pay"),
                new TeaPair("app_id", wap._kernel.getConfig("appId")),
                new TeaPair("timestamp", wap._kernel.getTimestamp()),
                new TeaPair("format", "json"),
                new TeaPair("version", "1.0"),
                new TeaPair("alipay_sdk", wap._kernel.getSdkVersion()),
                new TeaPair("charset", "UTF-8"),
                new TeaPair("sign_type", wap._kernel.getConfig("signType")),
                new TeaPair("app_cert_sn", wap._kernel.getMerchantCertSN()),
                new TeaPair("alipay_root_cert_sn", wap._kernel.getAlipayRootCertSN()));
        Map<String, Object> bizParams = TeaConverter.buildMap(
                new TeaPair("subject", subject),
                new TeaPair("out_trade_no", outTradeNo),
                new TeaPair("total_amount", totalAmount),
                new TeaPair("quit_url", quitUrl),
                new TeaPair("product_code", "QUICK_WAP_WAY"));
        Map<String, String> textParams = TeaConverter.buildMap(new TeaPair("return_url", returnUrl));
        String sign = wap._kernel.sign(systemParams, bizParams, textParams, wap._kernel.getConfig("merchantPrivateKey"));
        Map<String, String> response = TeaConverter.buildMap(
                new TeaPair("body", wap._kernel.generatePage("GET", systemParams, bizParams, textParams, sign)));
        return TeaModel.toModel(response, new AlipayTradeWapPayResponse());
    }
    /**
     * 订单状态查询
     */
    public AlipayTradeQueryResponse queryOrderPay(PayRequestEntity payRequestEntity) throws Exception {
        initOptions();
        return Factory.Payment.Common().query(payRequestEntity.getPayTransactionId()+"");
    }
    /**
     * 验证回调验签
     */
    public boolean verifySign(Map<String, String> params) throws Exception {
        initOptions();
        return Factory.Payment.Common().verifyNotify(params);
    }
}
